<?php

namespace App\Library\Service;

use App\Library\Logic\PaymentRelatedLogic;
use App\Library\Logic\ZbBailLogic;
use App\Library\Requests\ZbCash\ZbCashPaymentRequest;
use App\Library\Service\Payment\WechatService;
use App\Library\YsdLib;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Yansongda\Artful\Exception\ContainerException;
use Yansongda\Artful\Exception\InvalidParamsException;
use Yansongda\Artful\Exception\ServiceNotFoundException;
use Yansongda\Pay\Pay;

class ZbBailService extends BaseService
{
    /**
     * @param ZbBailLogic $logic
     */
    public function __construct(ZbBailLogic $logic)
    {
        $this->logic = $logic;
    }

    /**
     * 拉起支付
     * @param ZbCashPaymentRequest $request
     * @return JsonResponse
     * @throws Exception|GuzzleException
     */
    public function payment(ZbCashPaymentRequest $request): JsonResponse
    {
        $zbCash = $this->logic->last($request->money);
        if (is_null($zbCash) || $zbCash->status_refund === 1) $zbCash = $this->logic->add($request->money);
        if ($zbCash->status_pay === 1 && $zbCash->status_refund === 0) return failMessage('保证金已缴纳');
        $where = ['objectId' => $zbCash->id, 'objectType' => $zbCash->getTable()];
        $paymentRelated = PaymentRelatedLogic::add($where);
        Pay::config(YsdLib::config());
        return WechatService::mini($zbCash, $paymentRelated->serial_number, $request->code);
    }

    /**
     * 退款
     * @return JsonResponse
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public function refund(): JsonResponse
    {
        $zbBail = $this->logic->current();
        if (is_null($zbBail)) return fail(422);
        else if ($zbBail->status_pay === 0) return failMessage('保证金未支付');
        else if ($zbBail->status_refund === 1) return failMessage('保证金已经退款');
        else if (is_null($zbBail->paymentRelated)) return fail(422);
        else if (is_null($zbBail->payment)) return fail(422);
        $result = Pay::wechat(YsdLib::config())->refund([
            'transaction_id' => $zbBail->payment->out_trade_no,
            'out_trade_no' => $zbBail->paymentRelated->serial_number,
            'out_refund_no' => $zbBail->serial_number,
            'reason' => '退款',
            'notify_url' => config('app.url') . 'wechat/zbBailRefund',
            'amount' => [
                'refund' => prod() ? (int)bcmul($zbBail->pay_price, 100) : 1,
                'total' => prod() ? (int)bcmul($zbBail->pay_price, 100) : 1,
                'currency' => 'CNY',
            ],
        ]);
        $zbBail->status_refund = 99;
        $zbBail->save();
        payLog($result->toArray());
        return success();
    }

    /**
     * 状态
     * @return JsonResponse
     */
    public function current(): JsonResponse
    {
        return success($this->logic->current());
    }
}
